import request from '@/utils/request.js';
import Common from '@/utils/Common';
import tables from '@/utils/db/tables';

var tableMap = tables.map;

function remove(tableName, ids) {
	let table = tableMap[tableName];
	let sql = "delete from " + tableName + " where id = ?";
	let sqlBatches = [];
	for(let i = 0; i < ids.length; i++) {
		let values = [ids[i]];
		sqlBatches.push([sql, values]);
	}
	return Common.sqlBatch(sqlBatches);
}

function update(tableName, elements) {
	let table = tableMap[tableName];
	let columnNames = [];
	for(let i = 0; i < table.columns.length; i++) {
		let column = table.columns[i];
		if(column.name != 'id') {
			columnNames.push(column.name);
		}
	}
	let sql = "update " + tableName + " set ";
	sql += columnNames.map(columnName => {
		return columnName += ' = ?'
	}).join(',') + " ";
	sql += "where id = ? ";
	let sqlBatches = [];
	for(let i = 0; i < elements.length; i++) {
		let element = elements[i];
		let values = [];
		for(let i = 0; i < columnNames.length; i++) {
			let columnName = columnNames[i];
			let columnHumpName = Common.toHump(columnName);
			let value = element[columnHumpName];
			values.push(value);
		}
		values.push(element.id);
		sqlBatches.push([sql, values]);
	}
	return Common.sqlBatch(sqlBatches);
}

function insert(tableName, elements) {
	let table = tableMap[tableName];
	let columnNames = [];
	for(let i = 0; i < table.columns.length; i++) {
		let column = table.columns[i];
		columnNames.push(column.name);
	}
	let sql = "insert into " + tableName + " ";
	sql += "(" + columnNames.join(',') + ") ";
	sql += "values (" + columnNames.map(e => {return '?'}).join(',') + ")";
	let sqlBatches = [];
	for(let i = 0; i < elements.length; i++) {
		let element = elements[i];
		let values = [];
		for(let i = 0; i < columnNames.length; i++) {
			let columnName = columnNames[i];
			let columnHumpName = Common.toHump(columnName);
			let value = element[columnHumpName];
			values.push(value);
		}
		sqlBatches.push([sql, values]);
	}
	return Common.sqlBatch(sqlBatches);
}

function sync(entityName, tableName) {
	let url = "/api/" + entityName + "/findAll";
	let remoteMap = {};
	let localMap = {};
	let deleteCount = 0;
	let updateCount = 0;
	let insertCount = 0
	return request({
		url: url,
		method: 'get',
		timeout: 60000 * 5,
	}).then(data => {
		for(let i = 0; i < data.list.length; i++) {
			let remote = data.list[i];
			remoteMap[remote.id] = remote;
		}
		let sql = "select id, update_time from " + tableName; 
		return Common.executeSql(sql, []);
	}).then(result => {
		let rs = result.rs;
		for(let i = 0; i < rs.rows.length; i++) {
			let local = rs.rows.item(i);
			localMap[local.id] = local;
		}
		let ids = [];		
		for(let localId in localMap) {
			if(remoteMap[localId] == null) {
				ids.push(localId);
				delete localMap[localId];
			}
		}
		deleteCount = ids.length;
		return remove(tableName, ids);
	}).then(() => {
		let elements = [];
		for(let localId in localMap) {
			let local = localMap[localId];
			let remote = remoteMap[localId];
			if(local.update_time != remote.updateTime) {
				elements.push(remote);
			}
		}
		updateCount = elements.length;
		return update(tableName, elements);
	}).then(() => {
		let elements = [];
		for(var remoteId in remoteMap) {
			if(localMap[remoteId] == null) {
				let remote = remoteMap[remoteId];
        		elements.push(remote);
			}
		}
		insertCount = elements.length;
		return insert(tableName, elements);
	}).then(() => {
		return Promise.resolve({tableName, entityName, deleteCount, updateCount, insertCount});
	}).catch(error => {
		console.error(error);
		return Promise.resolve();
	});
}
export default {
	remove,
	update,
	insert,
	sync
}